home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / prog_c / cuj0696.zip / DWYER.ZIP / GAP.TST / SETGAP.C < prev    next >
C/C++ Source or Header  |  1996-01-08  |  9KB  |  267 lines

  1. /* ============ */
  2. /* setgap.c    */
  3. /* ============ */
  4. #include <io.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <float.h>
  8. #include <miscdefs.h>
  9. #include <gapdefs.h>
  10. #include <math.h>
  11. #include <maxgapln.c>
  12. #define    ACT(X)    #X
  13.  
  14. #define    CLAMP(Var, Lo, Hi)    __min(Hi, __max(Lo, Var))
  15.  
  16. #define    NEED_MIN_CELL_EXPECT(LO, HI) \
  17.     "Enter Minimum Cell Expectation ["ACT(LO)"-"ACT(HI)"]: "
  18.  
  19. #define    NEED_NUMBER_GAPS(LO, HI) \
  20.     "Enter Number of Gaps to be Tabulated ["\
  21.         ACT(LO)"-"ACT(HI)"]: "
  22.  
  23. #define    REPORT_USER_DBL_ENTRY(Entry, Label)        \
  24.     {                            \
  25.     fflush(NULL);printf("\n");            \
  26.     printf("\tNumber Entered:  %.6f", Entry);    \
  27.     printf(" (%s)\n", Label);            \
  28.     }
  29. #define    REPORT_USER_INT_ENTRY(Entry, Label)        \
  30.     {                            \
  31.     fflush(NULL);printf("\n");            \
  32.     printf("\tNumber Entered:  %.f", (double)Entry);\
  33.     printf(" (%s)\n", Label);            \
  34.     }
  35. #define    SHOW_DBL_VALUE_USED(Entered, Used)             \
  36.     printf("\tTest Value Used: %.6f%s\n", (double)Used,    \
  37.     ((double)Entered == (double)Used) ? "" : " (Clamped)")
  38.  
  39. #define    SHOW_INT_VALUE_USED(Entered, Used)             \
  40.     printf("\tTest Value Used: %.f%s\n", (double)Used,    \
  41.     ((double)Entered == (double)Used) ? "" : " (Clamped)")
  42.  
  43. static    double    CellExpect[MAX_GAP_LEN+1];
  44. static    double    GapProbs[MAX_GAP_LEN+1];
  45. /* ==================================================================== */
  46. /*  SetGapControls - Puts Run Controls in GapData structure    */
  47. /* ==================================================================== */
  48. void
  49. SetGapControls(GAP_DATA_STRU *GapData)
  50. {
  51.     int     k, MaxGapLen, NewlineCh, WhereMin;
  52.     long    MinGapCt;
  53.     char    Prompt[64];
  54.  
  55.     double  UserDblEntry;
  56.     int     UserIntEntry;
  57.     long    UserLongEntry;
  58.  
  59.     NewlineCh = _isatty(_fileno(stdin)) ? '\r' : '\n';
  60.  
  61.     /* -------------------------------------------- */
  62.     /* Request Lower Boundary of Gap, L: 0 <= L < 1 */
  63.     /* -------------------------------------------- */
  64.     GetDbl("Enter Lower Boundary (L) of Gap [0 <= L < 1]: ",
  65.     &UserDblEntry);
  66.  
  67.     REPORT_USER_DBL_ENTRY(UserDblEntry, "Lower Boundary of Gap");
  68.  
  69.     GapData->GapLoLimit =
  70.     CLAMP(UserDblEntry, 0.0,
  71.         ((double)RAND_MAX-1)/((double)RAND_MAX+1));
  72.  
  73.     SHOW_DBL_VALUE_USED(UserDblEntry, GapData->GapLoLimit);
  74.  
  75.     GapData->LoGapInt = (UINT)
  76.     ceil(GapData->GapLoLimit * ((double)RAND_MAX+1));
  77.  
  78.     /* -------------------------------------------- */
  79.     /* Request Upper Boundary of Gap, U: L < U <= 1 */
  80.     /* -------------------------------------------- */
  81.     fflush(NULL); fprintf(stderr, "%c", NewlineCh);
  82.     sprintf(Prompt,
  83.     "Enter Upper Boundary (U) of Gap [%f < U <= 1]: ",
  84.     GapData->GapLoLimit);
  85.  
  86.     GetDbl(Prompt, &UserDblEntry);
  87.  
  88.     REPORT_USER_DBL_ENTRY(UserDblEntry, "Upper Boundary of Gap");
  89.  
  90.     GapData->GapHiLimit =
  91.     CLAMP(UserDblEntry, GapData->GapLoLimit, 1.0);
  92.  
  93.     SHOW_DBL_VALUE_USED(UserDblEntry, GapData->GapHiLimit);
  94.  
  95.     GapData->HiGapInt = (UINT)
  96.     ceil(GapData->GapHiLimit * ((double)RAND_MAX+1));
  97.  
  98.     P(printf("Integer Value of Lower Boundary: %u\n"
  99.          "Integer Value of Upper Boundary: %u\n",
  100.         GapData->LoGapInt, GapData->HiGapInt));
  101.  
  102.     if (GapData->HiGapInt - GapData->LoGapInt > RAND_MAX)
  103.     {
  104.     fflush(NULL); fprintf(stderr, "%c", NewlineCh);
  105.     fprintf(stderr,
  106.         "You Have Specified Gap Limits 0 and 1. "
  107.         "Please Reenter.\n");
  108.     exit(1);
  109.     }
  110.  
  111.     if (GapData->HiGapInt <= GapData->LoGapInt+163)
  112.     {
  113.     fflush(NULL); fprintf(stderr, "%c", NewlineCh);
  114.     fprintf(stderr,
  115.         "The Difference Between the Lower Boundary (%.15g)\nand the"
  116.         " Upper Boundary (%.15g) is not Great Enough (%.8g)\n"
  117.         "You should specify limits that differ by .005 or more.\n",
  118.         GapData->GapLoLimit, GapData->GapHiLimit,
  119.         GapData->GapHiLimit - GapData->GapLoLimit);
  120.     exit(1);
  121.     }
  122.  
  123.     WhereMin = GetMaxGapLen(GapData->GapLoLimit, GapData->GapHiLimit,
  124.     MIN_CELL_XPCT, MAX_NUM_GAPS, MAX_GAP_LEN, GapProbs, &MinGapCt);
  125.  
  126.     P(printf("WhereMin = %d, MinGapCt = %d\n", WhereMin, MinGapCt));
  127.     /* ---------------------------------------- */
  128.     /* Request Maximum Gap Length to be Tallied */
  129.     /* ---------------------------------------- */
  130.     fflush(NULL); fprintf(stderr, "%c", NewlineCh);
  131.     MaxGapLen = (WhereMin-1 > MIN_GAP_LEN) ? WhereMin-1 : MIN_GAP_LEN;
  132.     sprintf(Prompt, "Enter Maximum Gap Length [%d-%d]: ", MIN_GAP_LEN,
  133.     MaxGapLen);
  134.  
  135.     GetInt(Prompt, &UserIntEntry);
  136.  
  137.     REPORT_USER_INT_ENTRY(UserIntEntry, "Maximum Gap Length");
  138.  
  139.     GapData->MaxGapLen =
  140.     CLAMP(UserIntEntry, MIN_GAP_LEN, MaxGapLen);
  141.  
  142.     SHOW_INT_VALUE_USED(UserIntEntry, GapData->MaxGapLen);
  143.  
  144.     /* -------------------------------------- */
  145.     /* Calculate & Store Number of Categories */
  146.     /* -------------------------------------- */
  147.     GapData->NumCategories = GapData->MaxGapLen + 1;
  148.  
  149.     /* -------------------------------- */
  150.     /* Request Minimum Cell Expectation    */
  151.     /* -------------------------------- */
  152.     fflush(NULL); fprintf(stderr, "%c", NewlineCh);
  153.     GetInt(NEED_MIN_CELL_EXPECT(MIN_CELL_XPCT, MAX_CELL_XPCT),
  154.     &UserIntEntry);
  155.  
  156.     REPORT_USER_INT_ENTRY(UserIntEntry, "Minimum Cell Expectation");
  157.  
  158.     /* ---------------- */
  159.     /* Clamp CellExpect */
  160.     /* ---------------- */
  161.     GapData->UserCellExpect =
  162.     __min(MAX_CELL_XPCT, __max(MIN_CELL_XPCT, UserIntEntry));
  163.  
  164.     SHOW_INT_VALUE_USED(UserIntEntry, GapData->UserCellExpect);
  165.  
  166.     /* -------------------------------------------------------- */
  167.     /* Calculate Probabilities Based on Data Width & Gap Length */
  168.     /* Recall That NumCategories = MaxGapLen + 1        */
  169.     /* -------------------------------------------------------- */
  170.     CalcGapProbs(GapData->NumCategories,
  171.          GapData->GapLoLimit,
  172.          GapData->GapHiLimit,
  173.          GapProbs);
  174.  
  175.     /* ------------------------------------------------------------- */
  176.     /* Compute Number Gaps Needed to Deliver User's Cell Expectation */
  177.     /*    and  Number Gaps Needed to Deliver Minimum Expectation.    */
  178.     /* ------------------------------------------------------------- */
  179.     GapData->UserNumGaps  = -1;
  180.     GapData->IdealNumGaps = -1;
  181.  
  182.     for (k = 0; k < GapData->NumCategories; ++k)
  183.     {
  184.     long    NextGap;
  185.  
  186.     if (GapProbs[k] == 0)
  187.     {
  188.         continue;
  189.     }
  190.     NextGap = (long)
  191.         (floor(0.5 + GapData->UserCellExpect/GapProbs[k]));
  192.     GapData->UserNumGaps = __max(NextGap, GapData->UserNumGaps);
  193.  
  194.     NextGap = (long)
  195.         floor(0.5 + MIN_CELL_XPCT/GapProbs[k]);
  196.  
  197.     GapData->IdealNumGaps = __max(NextGap, GapData->IdealNumGaps);
  198.     }
  199.  
  200.     /* ------------------------------------------------- */
  201.     /* Get User-Specified Number of Gaps to Be Tabulated */
  202.     /* ------------------------------------------------- */
  203.     fflush(NULL); fprintf(stderr, "%c", NewlineCh);
  204.     sprintf(Prompt, "How Many Gaps Are To Be Tabulated?"
  205.                 "  [%ld ...]: ", GapData->UserNumGaps);
  206.  
  207.     GetLong(Prompt, &UserLongEntry);
  208.  
  209.     REPORT_USER_INT_ENTRY(UserLongEntry, "Number of Gaps to be Tabulated");
  210.  
  211.     GapData->NumGaps = (UserLongEntry > GapData->UserNumGaps) ?
  212.             UserLongEntry : GapData->UserNumGaps;
  213.  
  214.     SHOW_INT_VALUE_USED(UserLongEntry, GapData->NumGaps);
  215.  
  216.     /* -------------------------------------------------- */
  217.     /* Calculate Cell Expectations Based on Probabilities */
  218.     /* -------------------------------------------------- */
  219.     for (k = 0; k < GapData->NumCategories; ++k)
  220.     {
  221.     CellExpect[k] = GapProbs[k] * GapData->NumGaps;
  222.     P(printf("GapProbs[%2d] = %f, CellExpect[%2d] = %17.11f\n",
  223.         k, GapProbs[k], k, CellExpect[k]));
  224.     }
  225.  
  226.     /* -------------------------------------------------- */
  227.     /* Lump lower-valued categories into next higher ones */
  228.     /* -------------------------------------------------- */
  229.     GapData->NotEnough = 0;
  230.     for (k = 0; k < GapData->NumCategories - 1; ++k)
  231.     {
  232.     double  NextInt = floor(0.5 + CellExpect[k]);
  233.     if (NextInt < GapData->UserCellExpect)
  234.     {
  235.         ++GapData->NotEnough;
  236. # if 0
  237.         CellExpect[k+1] += CellExpect[k];
  238.         CellExpect[k]    = 0;
  239. # endif
  240.     }
  241.     }
  242.    GapData->CellExpect = CellExpect;
  243.  
  244.     /* ------------------------------ */
  245.     /* Set Generator Failure Count to */
  246.     /* A Priori Mean + 100 * Std Dev. */
  247.     /* ------------------------------ */
  248.     {
  249.     double    GapMean, GapStdDev;
  250.  
  251.     CalcGapMeanStdDev(1,
  252.         GapData->GapHiLimit - GapData->GapLoLimit,
  253.         &GapMean, &GapStdDev);
  254.  
  255.     GapData->MaxGenPerGap = (long)
  256.         (ceil(GapMean) +
  257.         100 * ceil(GapStdDev));
  258.     }
  259.     fflush(NULL); fprintf(stderr, "%c", NewlineCh);
  260.     printf("\nFailure Count = %ld\n", GapData->MaxGenPerGap);
  261.     printf("\tA Complete Gap Should Have Been\n"
  262.        "\tTabulated Within This Many Variates.\n");
  263.     P(printf("NotEnough = %d\n", GapData->NotEnough));
  264.  
  265.     GapData->CallStatusOK = (GapData->NotEnough == 0);
  266. }
  267.